#include "SkyBox.h"
#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include "SOIL.h"

#define GL_CLAMP_TO_EDGE 0x812F

namespace steam
{

	namespace moon
	{

		SkyBox::SkyBox() : m_visible(false), m_scale(100), m_initialized(false)
		{
			//initialize("D:\\Resources\\SkyBox1", "PNG");
		}

		SkyBox::~SkyBox()
		{
			glDeleteTextures(6, m_imageId);
		}

		void SkyBox::initialize(std::string dirPath, std::string extention)
		{
			m_imageId[SKY_LEFT] = loadImage(dirPath + std::string("\\left.") + extention);

			m_imageId[SKY_BACK] = loadImage(dirPath + std::string("\\back.") + extention);

			m_imageId[SKY_RIGHT] = loadImage(dirPath + std::string("\\right.") + extention);

			m_imageId[SKY_FRONT] = loadImage(dirPath + std::string("\\front.") + extention);

			m_imageId[SKY_TOP] = loadImage(dirPath + std::string("\\top.") + extention);

			m_imageId[SKY_BOTTOM] = loadImage(dirPath + std::string("\\bottom.") + extention);

			m_initialized = true;
		}

		unsigned int SkyBox::loadImage( std::string filePath )
		{
			return SOIL_load_OGL_texture (
				filePath.c_str(),
				SOIL_LOAD_AUTO,
				SOIL_CREATE_NEW_ID,
				SOIL_FLAG_MIPMAPS | /*SOIL_FLAG_INVERT_Y |*/ SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
				);
		}

		void SkyBox::render()
		{
			if ( m_initialized && !m_visible )
				return;

			glDisable(GL_DEPTH_TEST);
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, m_imageId[SKY_FRONT]);
			glBegin(GL_QUADS);
			// Front Face
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f * m_scale, -1.0f * m_scale,  1.0f * m_scale);  // Bottom Left Of The Texture and Quad
			glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f * m_scale, -1.0f * m_scale,  1.0f * m_scale);  // Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f * m_scale,  1.0f * m_scale,  1.0f * m_scale);  // Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f * m_scale,  1.0f * m_scale,  1.0f * m_scale);  // Top Left Of The Texture and Quad
			glEnd();
			glBindTexture(GL_TEXTURE_2D, m_imageId[SKY_BACK]); 
			glBegin(GL_QUADS);
			// Back Face
			glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f * m_scale, -1.0f * m_scale, -1.0f * m_scale);  // Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f * m_scale,  1.0f * m_scale, -1.0f * m_scale);  // Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f * m_scale,  1.0f * m_scale, -1.0f * m_scale);  // Top Left Of The Texture and Quad
			glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f * m_scale, -1.0f * m_scale, -1.0f * m_scale);  // Bottom Left Of The Texture and Quad
			glEnd();
			glBindTexture(GL_TEXTURE_2D, m_imageId[SKY_TOP]);
			glBegin(GL_QUADS);
			// Top Face
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f * m_scale,  1.0f * m_scale, -1.0f * m_scale);  // Top Left Of The Texture and Quad
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f * m_scale,  1.0f * m_scale,  1.0f * m_scale);  // Bottom Left Of The Texture and Quad
			glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f * m_scale,  1.0f * m_scale,  1.0f * m_scale);  // Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f * m_scale,  1.0f * m_scale, -1.0f * m_scale);  // Top Right Of The Texture and Quad
			glEnd();
			glBindTexture(GL_TEXTURE_2D, m_imageId[SKY_BOTTOM]);
			glBegin(GL_QUADS);
			// Bottom face
			glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f * m_scale, -1.0f * m_scale, -1.0f * m_scale);  // Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f * m_scale, -1.0f * m_scale, -1.0f * m_scale);  // Top Left Of The Texture and Quad
			glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f * m_scale, -1.0f * m_scale,  1.0f * m_scale);  // Bottom Left Of The Texture and Quad
			glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f * m_scale, -1.0f * m_scale,  1.0f * m_scale);  // Bottom Right Of The Texture and Quad
			glEnd();
			glBindTexture(GL_TEXTURE_2D, m_imageId[SKY_RIGHT]);
			glBegin(GL_QUADS);		
			// Right face
			glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f * m_scale, -1.0f * m_scale, -1.0f * m_scale);  // Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f * m_scale,  1.0f * m_scale, -1.0f * m_scale);  // Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f * m_scale,  1.0f * m_scale,  1.0f * m_scale);  // Top Left Of The Texture and Quad
			glTexCoord2f(0.0f, 0.0f); glVertex3f(1.0f * m_scale, -1.0f * m_scale,  1.0f * m_scale);  // Bottom Left Of The Texture and Quad
			glEnd();
			glBindTexture(GL_TEXTURE_2D, m_imageId[SKY_LEFT]);
			glBegin(GL_QUADS);
			// Left Face
			glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f * m_scale, -1.0f * m_scale, -1.0f * m_scale);  // Bottom Left Of The Texture and Quad
			glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f * m_scale, -1.0f * m_scale,  1.0f * m_scale);  // Bottom Right Of The Texture and Quad
			glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f * m_scale,  1.0f * m_scale,  1.0f * m_scale);  // Top Right Of The Texture and Quad
			glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f * m_scale,  1.0f * m_scale, -1.0f * m_scale);  // Top Left Of The Texture and Quad
			glEnd();
			glDisable(GL_TEXTURE_2D);
			glEnable(GL_DEPTH_TEST);
		}

		void SkyBox::setVisible( bool visible )
		{
			m_visible = visible;
		}

	}
}